//
// Created by 朱林 on 2020/9/23.
//
#include <android/log.h>
#include <android/bitmap.h>
#include <jni.h>
#include <string>
#include <vector>
#include <iostream>
#include "base_util.h"
#include "multi_pose.h"
#include "opencv2/imgproc/types_c.h"

#define TAG "POSE"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG,__VA_ARGS__)

multiPose *detector;


extern "C"
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
    return JNI_VERSION_1_6;
}

extern "C"
JNIEXPORT void JNI_OnUnload(JavaVM *vm, void *reserved) {
    if (NULL != detector) {
        detector->~multiPose();
    }
}


extern "C"
JNIEXPORT jboolean JNICALL
Java_com_zl_pose_PoseDetector_initDetector(JNIEnv *env, jobject thiz, jstring mnn_path,
                                           jint num_thread, jboolean open_cl) {
    detector = new multiPose();
    std::string mnnPath = getFilePath(env, mnn_path);
    return detector->init(mnnPath, num_thread, open_cl);
}

extern "C"
JNIEXPORT jfloatArray JNICALL
Java_com_zl_pose_PoseDetector_detectPic(JNIEnv *env, jobject thiz, jstring img_path) {
    jfloatArray poseInfos = nullptr;
    const char *imgPath = env->GetStringUTFChars(img_path, 0);
    cv::Mat cv_img = cv::imread(imgPath);
    std::vector<Point> pose_info = detector->detect(cv_img);
    int32_t num_pose = static_cast<int32_t>(pose_info.size());
    LOGD("检测到的人脸数目：%d\n", num_pose);
    int poseSize = num_pose * 2;
    float *poses = new float[num_pose];
    for (int i = 0; i < num_pose; i++) {
        int startIndex = i * 2;
        poses[startIndex] = pose_info[i].x;
        poses[startIndex + 1] = pose_info[i].y;
    }
    poseInfos = env->NewFloatArray(poseSize);
    env->SetFloatArrayRegion(poseInfos, 0, poseSize, poses);
    return poseInfos;
}

extern "C"
JNIEXPORT jfloatArray JNICALL
Java_com_zl_pose_PoseDetector_detectYUV(JNIEnv *env, jobject thiz,
                                        jbyteArray yuv, jint width, jint height) {
    jfloatArray poseArgs = nullptr;
    jbyte *pBuf = (jbyte *) env->GetByteArrayElements(yuv, 0);
    cv::Mat image = cv::Mat(height + height / 2, width, CV_8UC1, (unsigned char *) pBuf);
    cv::Mat mBgr;
    cvtColor(image, mBgr, CV_YUV2BGR_NV21);
    std::vector<Point> pose_info = detector->detect(mBgr);
    env->DeleteLocalRef(yuv);
    int32_t num_pose = static_cast<int32_t>(pose_info.size());
    LOGD("检测到的人脸数目：%d\n", num_pose);
    int poseSize = num_pose * 2;
    float *poses = new float[poseSize];
    for (int i = 0; i < num_pose; i++) {
        int startIndex = i * 5;
        poses[startIndex] = pose_info[i].x;
        poses[startIndex + 1] = pose_info[i].y;
    }
    poseArgs = env->NewFloatArray(poseSize);
    env->SetFloatArrayRegion(poseArgs, 0, poseSize, poses);
    return poseArgs;
}